﻿using System;

namespace Beeflys
{
    public sealed class ActorId
    {
        internal const string DEFAULT_HOST = "loaclhost";
        
        public static ActorId Create(string tree, string name)
        {
            return ActorId.Create(DEFAULT_HOST, tree, name);
        }

        public static ActorId Create(string host, string tree, string name)
        {
            if (!InspectHostValid(host.AsSpan())) return null;
            if (!InspectTreeValid(tree.AsSpan())) return null;
            if (!InspectNameValid(name.AsSpan())) return null;

            return new ActorId(host, tree, name);
        }
        
        static bool InspectHostValid(in ReadOnlySpan<char> span)
        {
            return !(span.IndexOf('/') != -1 || span.IndexOf('\\') != -1 || span.IndexOf(' ') != -1);
        }
        
        static bool InspectTreeValid(in ReadOnlySpan<char> span)
        {
            return !(span.IndexOf(':') != -1 || span.IndexOf(' ') != -1);
        }

        static bool InspectNameValid(in ReadOnlySpan<char> span)
        {
            return !(span.IndexOf<char>('/') != -1 || span.IndexOf<char>('\\') != -1 || span.IndexOf(':') != -1 || span.IndexOf(' ') != -1);
        }
        
        private ActorId(string host, string tree, string name)
        {
            this.Address = new ActorAddress();
            this.Address.Name = name;
            this.Address.Tree = tree;

            this.Host = host;
            this.FullName = string.IsNullOrEmpty(this.Tree) ? this.Name : $"{this.Tree}/{this.Name}";
            this.FullAddress = $"actor://{this.Host}//{this.FullName}";
        }
        
        public ActorAddress Address
        {
            get;
            private set;
        }

        public string Host
        {
            get; private set;
        }

        public string Tree
        {
            get { return this.Address.Tree; }
        }

        public string Name
        {
            get { return this.Address.Name; }
        }

        public string FullName
        {
            get; private set;
        }

        public string FullAddress
        {
            get; private set;
        }
    }
}